#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QTime>
#include <QDebug>
#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent),
      ui(new Ui::MainWindow),
      visualizer(nullptr),
      sortAlgorithm(nullptr),
      timer(new QTimer(this)),
      compareCount(0),
      swapCount(0)
{
    ui->setupUi(this);

    // 临时关闭信号，防止 addItem 触发 createNewSort()
    ui->algorithmComboBox->blockSignals(true);

    // 添加排序算法选项
    ui->algorithmComboBox->addItem("快速排序");
    ui->algorithmComboBox->addItem("冒泡排序");
    ui->algorithmComboBox->addItem("插入排序");
    ui->algorithmComboBox->addItem("选择排序");
    ui->algorithmComboBox->addItem("归并排序");
    ui->algorithmComboBox->addItem("堆排序");
    ui->algorithmComboBox->addItem("希尔排序");

    // 添加查找算法选项
    ui->searchAlgorithmComboBox->addItem("线性查找");
    ui->searchAlgorithmComboBox->addItem("二分查找");
    ui->searchAlgorithmComboBox->addItem("插值查找");

    // 恢复信号
    ui->algorithmComboBox->blockSignals(false);

    // 初始化排序图表组件
    visualizer = new SortVisualizerWidget(this);
    QVBoxLayout* visualizerLayout = new QVBoxLayout(ui->sortVisualizerWidget);
    visualizerLayout->setContentsMargins(0, 0, 0, 0);
    visualizerLayout->addWidget(visualizer);
    visualizer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    setupConnections();
    createNewSort();

    ui->targetInput->setPlaceholderText("请输入 20 - 319 范围内的整数");
}


MainWindow::~MainWindow() {
    delete sortAlgorithm;
    delete ui;
}

void MainWindow::setupConnections() {
    // 初始化时更新一次排序速度
    int speed = ui->speedSlider->value();
    int interval = static_cast<int>(300 - ((speed - 1) * 2.727));
    ui->sizeValueLabel->setText(QString::number(ui->sizeSlider->value()));
    ui->speedValueLabel->setText(QString("%1 ms").arg(interval));

    connect(ui->startButton, &QPushButton::clicked, this, &MainWindow::onStartClicked);
    connect(ui->pauseButton, &QPushButton::clicked, this, &MainWindow::onPauseClicked);
    connect(ui->resetButton, &QPushButton::clicked, this, &MainWindow::onResetClicked);
    connect(ui->generateButton, &QPushButton::clicked, this, &MainWindow::onGenerateClicked);
    connect(ui->sortStepButton, &QPushButton::clicked, this, &MainWindow::onSortStepClicked);
    connect(ui->searchStepButton, &QPushButton::clicked, this, &MainWindow::onSearchStepClicked);
    connect(timer, &QTimer::timeout, this, &MainWindow::onTimeout);

    // 滑动条同步显示标签
    connect(ui->sizeSlider, &QSlider::valueChanged, this, [=](int value){
        ui->sizeValueLabel->setText(QString::number(value));
    });
    connect(ui->speedSlider, &QSlider::valueChanged, this, [=](int value){
        ui->speedValueLabel->setText(QString::number(value));
    });
    connect(ui->speedSlider, &QSlider::valueChanged, this, [=](int value){
        int interval = static_cast<int>(300 - ((value - 1) * 2.727));
        ui->speedValueLabel->setText(QString("%1 ms").arg(interval));
    });

    // 算法切换自动触发 createNewSort()
    connect(ui->algorithmComboBox, &QComboBox::currentTextChanged, this, &MainWindow::createNewSort);
    // 排序方式切换自动触发 createNewSort()
    connect(ui->orderComboBox, &QComboBox::currentTextChanged, this, &MainWindow::createNewSort);

    // 开始查找
    connect(ui->startSearchButton, &QPushButton::clicked, this, &MainWindow::onStartSearchClicked);
    connect(ui->randomTargetButton, &QPushButton::clicked, this, &MainWindow::onRandomTargetButtonClicked);
    connect(ui->searchAlgorithmComboBox, &QComboBox::currentTextChanged, this, &MainWindow::createLegendForSearch);
}

void MainWindow::onStartClicked() {
    if (!sortAlgorithm || sortAlgorithm->isFinished()) {
        createNewSort();
    }

    startTime.restart();
    // 动态调整速度
    int speed = ui->speedSlider->value(); // 1~100
    int interval = 300 - ((speed - 1) * 2.727); // 映射范围 [300, 30]
    timer->start(static_cast<int>(interval));

    ui->statusLabel->setText("排序中...");
}

void MainWindow::onPauseClicked() {
    timer->stop();
    ui->statusLabel->setText("已暂停");
}

void MainWindow::onResetClicked() {
    timer->stop();
    compareCount = 0;
    swapCount = 0;
    createNewSort();
    ui->statusLabel->setText("等待中");
}

void MainWindow::onGenerateClicked() {
    onResetClicked();
}

void MainWindow::onStartSearchClicked()
{
    bool ok = false;
    int target = ui->targetInput->text().toInt(&ok);

    if (!ok || target < 20 || target > 319) {
        ui->searchStatusLabel->setText("⚠️ 请输入 20 到 319 的整数！");
        return;
    }

    clearAllState();

    // 禁用排序算法互斥处理
    if (sortAlgorithm) {
        delete sortAlgorithm;
        sortAlgorithm = nullptr;
        ui->statusLabel->setText("排序已中止，进行查找");
    }

    if (searchAlgorithm) {
        delete searchAlgorithm;
        searchAlgorithm = nullptr;
    }

    QString searchAlgo = ui->searchAlgorithmComboBox->currentText();

    if (searchAlgo == "线性查找") {
        searchAlgorithm = new LinearSearch(values);
    } else if (searchAlgo == "二分查找") {
        searchAlgorithm = new BinarySearch(values);
    } else if (searchAlgo == "插值查找") {
        searchAlgorithm = new InterpolationSearch(values);
    } else {
        ui->searchStatusLabel->setText("未知查找算法");
        return;
    }

    searchAlgorithm->setTarget(target);
    ui->searchStatusLabel->setText("查找中...");
    createLegendForSearch(searchAlgo);

    // 判断是否为手动执行模式
    bool isManual = ui->manualSearchCheckBox->isChecked();
    if (!isManual) {
        // 根据速度滑动条设置查找计时器间隔
        int speed = ui->speedSlider->value();
        int interval = 300 - ((speed - 1) * 2.727);
        timer->start(static_cast<int>(interval));
    } else {
        ui->searchStatusLabel->setText("查找准备就绪，请使用“查找单步”按钮手动执行");
    }

}

void MainWindow::onRandomTargetButtonClicked()
{
    int randomIndex = qrand() % values.size();
    int target = values[randomIndex];
    ui->targetInput->setText(QString::number(target));
}

void MainWindow::onTimeout() {
    if (searchAlgorithm) {
        if (!searchAlgorithm->isFinished()) {
            searchAlgorithm->step();
            visualizer->updateWithData(searchAlgorithm->getData());
            compareCount += searchAlgorithm->getAndResetCompareCount();
            updateUI();
            return;
        } else {
            timer->stop();
            visualizer->updateWithData(searchAlgorithm->getData());
            if (searchAlgorithm->isFound()) {
                int index = searchAlgorithm->getFoundIndex();
                QVector<SortBar> finalBars = searchAlgorithm->getData();
                if (index >= 0 && index < finalBars.size()) {
                    finalBars[index].color = QColor("limegreen");
                    visualizer->updateWithData(finalBars);
                }
                ui->searchStatusLabel->setText(QString("✅ 找到目标值，位置：%1 🎯").arg(index));
            } else {
                ui->searchStatusLabel->setText("❌ 未找到目标值");
            }
            return;
        }
    }

    if (sortAlgorithm) {
        if (!sortAlgorithm->isFinished()) {
            sortAlgorithm->step();
            visualizer->updateWithData(sortAlgorithm->getData());
            compareCount += sortAlgorithm->getAndResetCompareCount();
            swapCount += sortAlgorithm->getAndResetSwapCount();
            updateUI();
        } else {
            timer->stop();
            ui->statusLabel->setText("完成");
        }
    }
}

void MainWindow::updateUI() {
    ui->compareLabel->setText(QString("比较次数：%1").arg(compareCount));
    ui->swapLabel->setText(QString("交换次数：%1").arg(swapCount));
    ui->timeLabel->setText(QString("用时：%1s").arg(startTime.elapsed() / 1000.0, 0, 'f', 1));
}

void MainWindow::createNewSort() {
    timer->stop(); // 停止当前排序任务
    ui->statusLabel->setText("等待中");
    clearAllState();
    QString orderText = ui->orderComboBox->currentText();
    SortOrder order = (orderText == "降序") ? SortOrder::Descending : SortOrder::Ascending;

    if (sortAlgorithm) {
        delete sortAlgorithm;
        sortAlgorithm = nullptr;
    }

    // 1. 获取当前数组大小
    int size = ui->sizeSlider->value();
    values.clear();
    for (int i = 0; i < size; ++i) {
        values.append(qrand() % 300 + 20);
    }
    std::random_shuffle(values.begin(), values.end());

    // 2. 根据下拉框选择实例化排序算法对象
    QString algo = ui->algorithmComboBox->currentText().trimmed();

    if (algo == "快速排序") {
        sortAlgorithm = new QuickSort(values);
    }
    else if (algo == "冒泡排序") {
        sortAlgorithm = new BubbleSort(values);
    }
    else if (algo == "插入排序") {
        sortAlgorithm = new InsertionSort(values);
    }
    else if (algo == "选择排序") {
        sortAlgorithm = new SelectionSort(values);
    }
    else if (algo == "归并排序") {
        sortAlgorithm = new MergeSort(values);
    }
    else if (algo == "堆排序") {
        sortAlgorithm = new HeapSort(values, order);
    }
    else if (algo == "希尔排序") {
        sortAlgorithm = new ShellSort(values);
    }
    else {
        qDebug() << "未知算法：" << algo;
        return;
    }

    sortAlgorithm->setOrder(order);

    // 3. 更新图表显示数据
    visualizer->updateWithData(sortAlgorithm->getData());

    // 4. 更新状态变量
    compareCount = 0;
    swapCount = 0;

    // 5. 更新复杂度信息标签
    ui->complexityLabel->setText(sortAlgorithm->getComplexityInfo());
    createLegendForAlgorithm(algo);
}

void MainWindow::createLegendForAlgorithm(const QString &algo) {
    // 清空 legendLayout
    QLayoutItem *child;
    while ((child = ui->legendLayout->takeAt(0)) != nullptr) {
        if (child->widget()) child->widget()->deleteLater();
        delete child;
    }

    // 辅助函数添加色块+说明
    auto addLegendItem = [&](const QString &color, const QString &text) {
        QLabel *colorBox = new QLabel;
        colorBox->setFixedSize(16, 16);
        colorBox->setStyleSheet(QString("background-color: %1; border: 1px solid black;").arg(color));
        QLabel *desc = new QLabel(text);

        QHBoxLayout *itemLayout = new QHBoxLayout;
        itemLayout->addWidget(colorBox);
        itemLayout->addWidget(desc);
        itemLayout->setSpacing(6);

        QWidget *container = new QWidget;
        container->setLayout(itemLayout);
        ui->legendLayout->addWidget(container);
    };

    // 根据算法定义图例颜色含义
    if (algo == "快速排序") {
        addLegendItem("red", "比较");
        addLegendItem("green", "交换");
        addLegendItem("darkblue", "Pivot 元素");
    } else if (algo == "冒泡排序") {
        addLegendItem("red", "比较");
        addLegendItem("green", "交换");
    } else if (algo == "插入排序") {
        addLegendItem("green", "插入位置");
        addLegendItem("red", "当前元素");
    } else if (algo == "选择排序") {
        addLegendItem("red", "扫描项");
        addLegendItem("green", "当前最小值");
        addLegendItem("darkblue", "当前排序位");
    } else if (algo == "归并排序") {
        addLegendItem("cyan", "合并区域");
    } else if (algo == "堆排序") {
        addLegendItem("red", "比较节点");
    } else if (algo == "希尔排序") {
        addLegendItem("green", "插入目标");
        addLegendItem("red", "当前元素");
    }

    // 添加排序方式说明文本
    QString explanation;

    if (algo == "快速排序") {
        explanation = "快速排序：选择一个基准数，把小的放左边，大的放右边，然后分别对左右继续这样分，直到排好。";
    } else if (algo == "冒泡排序") {
        explanation = "冒泡排序：从左到右比较两个数，把大的“冒”到右边，一轮一轮让大数排到最后。";
    } else if (algo == "插入排序") {
        explanation = "插入排序：将每个数插入到前面已经排好序的位置，就像打牌时整理手牌。";
    } else if (algo == "选择排序") {
        explanation = "选择排序：每次从剩下的数中挑出最小的，放到前面，重复直到排序完成。";
    } else if (algo == "归并排序") {
        explanation = "归并排序：先把数组一半一半分开，再一步步合并时排好序，像“分而治之”。";
    } else if (algo == "堆排序") {
        explanation = "堆排序：把所有数构成一个“堆”，每次取出最大或最小的放到后面。";
    } else if (algo == "希尔排序") {
        explanation = "希尔排序：先隔开排序，再逐步缩小间隔，最后整体有序。效率比插入快。";
    }

    if (!explanation.isEmpty()) {
        ui->legendPlaceholder->setWordWrap(true);
        ui->legendPlaceholder->setText(explanation);
    }
}

void MainWindow::createLegendForSearch(const QString &algo)
{
    QLayoutItem *child;
    while ((child = ui->legendLayout->takeAt(0)) != nullptr) {
        if (child->widget()) child->widget()->deleteLater();
        delete child;
    }

    auto addLegendItem = [&](const QString &color, const QString &text) {
        QLabel *colorBox = new QLabel;
        colorBox->setFixedSize(16, 16);
        colorBox->setStyleSheet(QString("background-color: %1; border: 1px solid black;").arg(color));
        QLabel *desc = new QLabel(text);

        QHBoxLayout *itemLayout = new QHBoxLayout;
        itemLayout->addWidget(colorBox);
        itemLayout->addWidget(desc);
        itemLayout->setSpacing(6);

        QWidget *container = new QWidget;
        container->setLayout(itemLayout);
        ui->legendLayout->addWidget(container);
    };

    QString explanation;

    if (algo == "线性查找") {
        addLegendItem("red", "当前比较元素");
        addLegendItem("green", "目标值");
        explanation = "线性查找：从头到尾依次查找目标值。";
    } else if (algo == "二分查找") {
        addLegendItem("red", "当前中点元素");
        addLegendItem("green", "目标值");
        explanation = "二分查找：折半查找目标值，数据必须有序。";
    } else if (algo == "插值查找") {
        addLegendItem("red", "估算位置元素");
        addLegendItem("green", "目标值");
        explanation = "插值查找：基于目标值估算其可能位置，更适合均匀分布数据。";
    }

    if (!explanation.isEmpty()) {
        ui->legendPlaceholder->setWordWrap(true);
        ui->legendPlaceholder->setText(explanation);
    }
}

void MainWindow::clearAllState()
{
    if (sortAlgorithm) {
        delete sortAlgorithm;
        sortAlgorithm = nullptr;
        ui->statusLabel->clear();
    }
    if (searchAlgorithm) {
        delete searchAlgorithm;
        searchAlgorithm = nullptr;
        ui->searchStatusLabel->clear();
    }
}

void MainWindow::onSortStepClicked() {
    if (timer->isActive()) timer->stop();

    if (sortAlgorithm && !sortAlgorithm->isFinished()) {
        sortAlgorithm->step();
        visualizer->updateWithData(sortAlgorithm->getData());
        compareCount += sortAlgorithm->getAndResetCompareCount();
        swapCount += sortAlgorithm->getAndResetSwapCount();
        updateUI();

        if (sortAlgorithm->isFinished()) {
            ui->statusLabel->setText("完成");
        }
    }
}

void MainWindow::onSearchStepClicked() {
    if (timer->isActive()) timer->stop();

    if (!searchAlgorithm) {
        ui->searchStatusLabel->setText("请先点击“开始查找”按钮！");
        return;
    }

    if (searchAlgorithm->isFinished()) {
        ui->searchStatusLabel->setText("查找已完成，请重新生成或开始新查找。");
        return;
    }

    // 执行一步
    searchAlgorithm->step();
    visualizer->updateWithData(searchAlgorithm->getData());
    compareCount += searchAlgorithm->getAndResetCompareCount();
    updateUI();

    // 查找结束反馈
    if (searchAlgorithm->isFinished()) {
        int index = searchAlgorithm->getFoundIndex();
        QVector<SortBar> finalBars = searchAlgorithm->getData();
        if (searchAlgorithm->isFound() && index >= 0 && index < finalBars.size()) {
            finalBars[index].color = QColor("limegreen");
            visualizer->updateWithData(finalBars);
            ui->searchStatusLabel->setText(QString("✅ 找到目标值，位置：%1 🎯").arg(index));
        } else {
            ui->searchStatusLabel->setText("❌ 未找到目标值");
        }
    }
}

